<?php


namespace App\Http\Controllers;

use App\Models\CollectFile;
use App\Models\File;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\UserFile;

class UserFileController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    //获取根目录id
    public function getRootInfo(){
        $user = Auth::user();
        $folder_id = UserFile::where('user_id', $user->id)
            ->where('parent_id', 0)
            ->where('type', UserFile::TYPE_FOLDER)
            ->value('id');
        $public_folder_id = UserFile::where('is_public', UserFile::IS_PUBLIC)
            ->where('parent_id', 0)
            ->where('type', UserFile::TYPE_FOLDER)
            ->value('id');
        $folders_num = UserFile::where('user_id', $user->id)
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('type', UserFile::TYPE_FOLDER)
            ->where('parent_id', '<>', '0')
            ->count();
        $files_num = UserFile::where('user_id', $user->id)
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('type', UserFile::TYPE_FILE)
            ->count();
        return ['code'=>0, 'data'=>['folder_id'=>$folder_id, 'public_folder_id'=>$public_folder_id,'folders_num'=>$folders_num, 'files_num'=>$files_num]];
    }
    //获取当前文件夹的父id
    public function getParentId(Request $request, $id){
        $user = Auth::user();
        $is_public = intval($request->input('is_public'));
        $parent_id = UserFile::where('id', $id)
            ->where(function($query) use($is_public,$user){
                if ($is_public == UserFile::IS_NOT_PUBLIC) {
                    $query->where('user_id', $user->id);
                }
            })
            ->value('parent_id');
        return ['code'=>0, 'data'=>['parent_id'=>$parent_id]];
    }
    //获取文件夹内容
    public function getFolderInfo(Request $request) {
        $user = Auth::user();
        $parent_id = intval($request->input('parent_id'));
        $is_public = intval($request->input('is_public'));
        $order = intval($request->input('order'));
        $key = intval($request->input('key'));
        //判断父级文件夹是否存在
        if($parent_id != 0){
            $parent_folder = UserFile::where('id', $parent_id)
                ->where(function($query) use($is_public,$user){
                    if ($is_public == UserFile::IS_NOT_PUBLIC) {
                        $query->where('user_id', $user->id);
                    }
                })
                ->where('status', UserFile::STATUS_NORMAL)
                ->where('type', UserFile::TYPE_FOLDER)
                ->first();
            if(empty($parent_folder)) {
                return ['code'=>1, "msg"=>"invalid parent folder"];
            }
        }
        $order_by = $this->_file_order($key, $order);
        //获取状态正常的文件夹和文件  排除分享链接
        $info = UserFile::where('user_files.parent_id', $parent_id)
            ->where(function($query) use($is_public,$user){
                if ($is_public == UserFile::IS_NOT_PUBLIC) {
                    $query->where('user_files.user_id', $user->id);
                }
            })
            ->where('user_files.status', UserFile::STATUS_NORMAL)
            ->where('user_files.type', '=', UserFile::TYPE_FILE)
            ->orderby($order_by['key'], $order_by['order'])
            ->join('files', 'files.id', '=', 'user_files.file_id')
            ->select('user_files.*')
            ->get();
        $folder_info['folder'] = UserFile::where('parent_id', $parent_id)
            ->where(function($query) use($is_public,$user){
                if ($is_public == UserFile::IS_NOT_PUBLIC) {
                    $query->where('user_id', $user->id);
                }
            })
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('type', '=', UserFile::TYPE_FOLDER)
            ->get();
        $folder_info['file'] = [];
        foreach($info as $k => $one){
            $collect_file = CollectFile::where('user_id', $user->id)->where('user_file_id', $one->id)->first();
            if(!empty($collect_file)){
                $one->collect_status = 1;
            }
            $file = File::where('id', $one->file_id)->select('mime', 'hash')->first();
            if(in_array($file->mime, ['image/jpeg', 'image/png'])){
                if(is_file(base_path().DIRECTORY_SEPARATOR.'public'.DIRECTORY_SEPARATOR.'thumb'.DIRECTORY_SEPARATOR.$file->hash.'.jpg')){
                    $one->thumb = '/thumb/'.$file->hash.'.jpg';
                }
            }
            $folder_info['file'][] = $one;
        }
        return ['code'=>0, 'data'=>['folder_info'=>$folder_info]];
    }

    public function createFolder(Request $request){
        $user = Auth::user();
        $folder_name = trim($request->input('name'));
        $parent_id = intval($request->input('parent_id'));
        $is_public = intval($request->input('is_public'));
        $user_file = new UserFile();
        $user_file->user_id = $user->id;
        $user_file->name = $folder_name;
        $user_file->status = UserFile::STATUS_NORMAL;
        $user_file->type = UserFile::TYPE_FOLDER;
        $user_file->parent_id = $parent_id;
        $user_file->is_public = $is_public;
        if($user_file->save()){
            return ['code'=>0, 'msg'=>'success'];
        }else{
            return ['code'=>1, 'msg'=>'save error'];
        }
    }

    //删除用户文件
    public function deleteUserFile($id){
        $this->deleteFolderOrFile($id);
        return ['code'=>0, 'msg'=>'success'];
    }

    private function deleteFolderOrFile($id){
        $user = Auth::user();
        $user_file = UserFile::where('user_id', $user->id)->where('id', $id)->first();
        if($user_file->type == UserFile::TYPE_FOLDER){
            UserFile::where('user_id', $user->id)->where('id', $id)->update(['status' => UserFile::STATUS_DELETED]);
            $user_files = UserFile::where('user_id', $user->id)->where('parent_id', $id)->get();
            foreach($user_files as $one){
                if($one->type == UserFile::TYPE_FOLDER){
                    $this->deleteFolderOrFile($one->id);
                }else{
                    //删除文件后恢复用户存储空间
                    $real_file = File::find($one->file_id);
                    $user->used_storage -= $real_file->storage_size;
                    $user->save();
                    UserFile::where('user_id', $user->id)->where('id', $one->id)->update(['status' => UserFile::STATUS_DELETED]);
                    CollectFile::where('user_file_id', $user_file->id)->delete();//所有相关收藏
                    UserFile::where('from_user_id', $user->id)->where('file_id', $one->file_id)->where('type', UserFile::TYPE_SHARE_LINK)->update(['status' => UserFile::STATUS_DELETED]);//分享链接
                }
            }
        }else{
            //删除文件后恢复用户存储空间
            $real_file = File::find($user_file->file_id);
            $user->used_storage -= $real_file->storage_size;
            $user->save();
            UserFile::where('user_id', $user->id)->where('id', $user_file->id)->update(['status' =>  UserFile::STATUS_DELETED]);
            CollectFile::where('user_file_id', $user_file->id)->delete();//所有相关收藏
            UserFile::where('from_user_id', $user->id)->where('file_id', $user_file->file_id)->where('type', UserFile::TYPE_SHARE_LINK)->update(['status' => UserFile::STATUS_DELETED]);//分享链接
        }
    }

    //获取文件详情
    public function detail(Request $request, $id){
        $user = Auth::user();
        $is_public = intval($request->input('is_public'));
        $detail = UserFile::where('user_files.id', $id)
            ->where(function($query) use($is_public,$user){
                if ($is_public == UserFile::IS_NOT_PUBLIC) {
                    $query->where('user_files.user_id', $user->id);
                }
            })
            ->where('user_files.status', UserFile::STATUS_NORMAL)
            ->join('files', 'user_files.file_id', '=', 'files.id')
            ->join('users', 'user_files.user_id', '=', 'users.id')
            ->select('user_files.*','files.storage_size','users.nickname as user_name','users.avatar as user_avatar')
            ->first();
        if(empty($detail)) {
            return ['code'=>1, "msg"=>"invalid file"];
        }
        if($detail->type == UserFile::TYPE_SHARE_LINK){
            $user = User::find($detail->from_user_id);
            if(!empty($user)){
                $detail->user_name = $user->nickname;
                $detail->user_avatar = $user->avatar;
            }
        }
        $collect_file = CollectFile::where('user_id', $user->id)->where('user_file_id',$detail->id)->first();
        if(!empty($collect_file)){
            $detail->collect_status = 1;
        }else{
            $detail->collect_status = 0;
        }
        $file = File::where('id', $detail->file_id)->select('mime', 'hash')->first();
        if(in_array($file->mime, ['image/jpeg', 'image/png'])){
            if(is_file(base_path().DIRECTORY_SEPARATOR.'public'.DIRECTORY_SEPARATOR.'thumb'.DIRECTORY_SEPARATOR.$file->hash.'.jpg')){
                $detail->thumb = '/thumb/'.$file->hash.'.jpg';
            }
        }
        $detail->user_avatar = urldecode($detail->user_avatar);
        if($detail->storage_size >= 1024 * 1024 * 1024){
            $detail->storage_size = number_format($detail->storage_size / (1024.0*1024.0*1024.0), 2).'TB';
        }elseif($detail->storage_size >= 1024 * 1024){
            $detail->storage_size = number_format($detail->storage_size / (1024.0*1024.0), 2).'GB';
        }elseif($detail->storage_size >= 1024){
            $detail->storage_size = number_format($detail->storage_size / 1024.0, 2).'MB';
        }else{
            $detail->storage_size = $detail->storage_size.'KB';
        }
        return ['code'=>0, 'data'=>['detail'=>$detail]];
    }

    //转发
    public function forward(Request $request, $id){
        $user = Auth::user();
        $is_public = intval($request->input('is_public'));
        $be_shared = UserFile::where('id', $id)
            ->where(function($query) use($is_public,$user){
                if ($is_public == UserFile::IS_NOT_PUBLIC) {
                    $query->where('user_id', $user->id);
                }
            })
            ->where('status', UserFile::STATUS_NORMAL)
            ->first();
        if(empty($be_shared)) {
            return ['code'=>1, "msg"=>"invalid file"];
        }
        $user_id_str = $request->input('atUserId');
        $user_id_list = explode(',', $user_id_str);
        foreach($user_id_list as $key => $value){
            if($value == $user->id || $value == $be_shared->user_id){
                continue;
            }
            $user_file = new UserFile();
            $user_file->user_id = $value;
            $user_file->file_id = $be_shared->file_id;
            $user_file->name = $be_shared->name;
            $user_file->access_token = str_random(16);
            $user_file->access_token_expire_at = date('Y-m-d H:i:s', time()+3*24*3600);
            $user_file->file_ext = $be_shared->file_ext;
            $user_file->status = UserFile::STATUS_NORMAL;
            $user_file->type = UserFile::TYPE_SHARE_LINK;
            $user_file->from_user_id = $user->id;
            $user_file->is_public = $is_public;
            if($user_file->save()===false) {
                continue;
            }
        }
        return ['code'=>0, 'msg'=>'success'];
    }

    //获取@我的文件
    public function  getLinks(Request $request){
        $user = Auth::user();
        $search_name = $request->input('name');
        $order = intval($request->input('order'));
        $key = intval($request->input('key'));
        $order_by = $this->_file_order($key, $order);
        $links = DB::table('user_files')
            ->where('user_files.user_id', $user->id)
            ->where(function($query) use($search_name){
                if (!empty($search_name)) {
                    $query->where('user_files.name', 'like', '%' . $search_name . '%');
                }
            })
            ->where('user_files.status',  UserFile::STATUS_NORMAL)
            ->where('user_files.type',  UserFile::TYPE_SHARE_LINK)
            ->orderby($order_by['key'], $order_by['order'])
            ->join('files', 'files.id', '=', 'user_files.file_id')
            ->select('user_files.*')
            ->get();
        foreach($links as $one) {
            $file = File::where('id', $one->file_id)->select('mime', 'hash')->first();
            if (in_array($file->mime, ['image/jpeg', 'image/png'])) {
                if (is_file(base_path() . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'thumb' . DIRECTORY_SEPARATOR . $file->hash . '.jpg')) {
                    $one->thumb = '/thumb/' . $file->hash . '.jpg';
                }
            }
        }
        return ['code'=>0, 'data'=>['files'=>$links]];
    }


    public function search(Request $request){
        $user = Auth::user();
        $name = $request->input('search_name');
        $folder_id = $request->input('folder_id');
        $public_folder_id = $request->input('public_folder_id');

        $results = $this->searchFolderOrFile($folder_id, $name);
        if(!empty($public_folder_id)){
            $public_results = $this->searchFolderOrFile($public_folder_id, $name);
            $results = array_merge($results, $public_results);
        }
        $folder_info['folder'] = [];
        $folder_info['file'] = [];
        foreach($results as $k => $one){
            if($one->type == UserFile::TYPE_FOLDER){
                $folder_info['folder'][] = $one;
            }elseif($one->type == UserFile::TYPE_FILE){
                $collect_file = CollectFile::where('user_id', $user->id)->where('user_file_id', $one->id)->first();
                if(!empty($collect_file)){
                    $one->collect_status = 1;
                }
                $file = File::where('id', $one->file_id)->select('mime', 'hash')->first();
                if(in_array($file->mime, ['image/jpeg', 'image/png'])){
                    if(is_file(base_path().DIRECTORY_SEPARATOR.'public'.DIRECTORY_SEPARATOR.'thumb'.DIRECTORY_SEPARATOR.$file->hash.'.jpg')){
                        $one->thumb = '/thumb/'.$file->hash.'.jpg';
                    }
                }
                $folder_info['file'][] = $one;
            }
        }
        return view('wap.list_search',['results'=>$folder_info]);
    }

    private function searchFolderOrFile($id, $name){
        $results = [];
        $user_files = UserFile::where('parent_id', $id)
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('type', '<>', UserFile::TYPE_SHARE_LINK)
            ->get();
        foreach($user_files as $one){
            if(strpos($one->name, $name) !== false){
                $results[] = $one;
            }
            if($one->type == UserFile::TYPE_FOLDER){
                $sub_results = $this->searchFolderOrFile($one->id, $name);
                foreach($sub_results as $one_sub){
                    if(count($one_sub) > 0){
                        $results[] = $one_sub;
                    }
                }
            }
        }
        return $results;
    }
    /**
     * 文件排序方式
     */
    private function _file_order($key, $order) {
        $result = 'user_files.id';
        $sequence = 'asc';
        if (!empty($key)) {
            $sequence = 'desc';
            if($order == 1) {
                $sequence = 'asc';
            }
            switch ($key) {
                //名称
                case '1' :
                    $result = 'user_files.name';
                    break;
                //大小
                case '2' :
                    $result = 'files.real_size';
                    break;
                //时间
                case '3' :
                    $result = 'user_files.updated_at';
                    break;
            }
        }
        return array('key'=>$result, 'order'=>$sequence);
    }

    /**
     * 文件或文件夹重命名
     */
    public function rename(Request $request, $id){
        $user = Auth::user();
        $name = $request->input('new_name');
        $user_file = UserFile::find($id);
        if(empty($user_file)) {
            return ['code'=>1, "msg"=>"invalid file"];
        }
        $user_file->name = $name;
        $user_file->save();
        UserFile::where('file_id', $user_file->file_id)
            ->where('type', UserFile::TYPE_SHARE_LINK)
            ->where('from_user_id', $user->id)
            ->update(['name'=>$name]);
        return ['code'=>0, 'msg'=>'success'];
    }

    /**
     * 获取个人当前文件夹可以移动到的所有文件夹
     */
    public function getAllFolders(Request $request){
        $user = Auth::user();
        $id = $request->input('user_file_id');
        $name = $request->input('name');
        //判断当前id是文件还是文件夹
        $user_file = UserFile::where('user_id', $user->id)
            ->where('id', $id)
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('is_public', UserFile::IS_NOT_PUBLIC)
            ->select('id', 'type')
            ->first();
        if($user_file->type == UserFile::TYPE_FILE){
            $id_list = [];
        }else{
            $id_list = $this->getSonFoldersId($id);
            $id_list[] = $id;
        }
        $folders = UserFile::where('user_id', $user->id)
            ->whereNotIn('id', $id_list)
            ->where(function($query) use($name){
                if (!empty($name)) {
                    $query->where('name', 'like', '%' . $name . '%');
                }
            })
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('type', UserFile::TYPE_FOLDER)
            ->where('is_public', UserFile::IS_NOT_PUBLIC)
            ->select('name', 'id', 'parent_id', 'updated_at')
            ->get();
        return ['code'=>0, 'data'=>['folders'=> $folders]];
    }

    private function getSonFoldersId($id){
        $id_list = [];
        $user = Auth::user();
        $user_files = UserFile::where('user_id', $user->id)
            ->where('parent_id', $id)
            ->where('status', UserFile::STATUS_NORMAL)
            ->where('is_public', UserFile::IS_NOT_PUBLIC)
            ->select('id', 'type')
            ->get();
        foreach($user_files as $one){
            if($one->type == UserFile::TYPE_FOLDER){
                $id_list[] = $one->id;
                $son_id_list = $this->getSonFoldersId($one->id);
                foreach($son_id_list as $one_son_id){
                    if(count($one_son_id) > 0){
                        $id_list[] = $one_son_id;
                    }
                }
            }
        }
        return $id_list;
    }
    /**
     * 文件或文件夹移动
     */
    public function moveToFolder(Request $request, $id){
        $folder_id = $request->input('folder_id');
        $user_file = UserFile::find($id);
        if(empty($user_file)) {
            return ['code'=>1, "msg"=>"invalid file"];
        }
        UserFile::where('id', $id)->update(['parent_id'=>$folder_id]);
        return ['code'=>0, 'msg'=>'success'];
    }
}
